package com.tianji.aigc.service.impl;

import cn.hutool.core.util.ObjectUtil;
import cn.hutool.extra.spring.SpringUtil;
import com.tianji.aigc.agent.Agent;
import com.tianji.aigc.agent.RouteAgent;
import com.tianji.aigc.domain.vo.ChatEventVO;
import com.tianji.aigc.enums.AgentTypeEnum;
import com.tianji.aigc.enums.ChatEventTypeEnum;
import com.tianji.aigc.service.IChatService;
import jakarta.annotation.PostConstruct;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import reactor.core.publisher.Flux;

import java.util.EnumMap;
import java.util.Map;

import static com.tianji.aigc.agent.AbstractAgent.STOP_EVENT;

/**
 * @author Administrator
 * @version 1.0
 * @description: TODO
 * @date 2025/7/24 17:22
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AgentServiceImpl implements IChatService {
    private final RouteAgent routeAgent;

    /**
     * 1、流式聊天 （Day1 - 随堂3）
     *
     * @param question
     * @param sessionId
     * @return
     */
    @Override
    public Flux<ChatEventVO> chat(String question, String sessionId) {
        // 1、使用路由智能体，推断用户意图
        String result = routeAgent.chat(question, sessionId);

        // 2、根据返回的用户意图，选择对应的智能体
        AgentTypeEnum agentType = AgentTypeEnum.agentNameOf(result);
        Agent nextAgent = this.findAgentByType(agentType);

        // 3、如果智能体为空，直接返回第一个智能体的输出结果
        if(ObjectUtil.isEmpty(nextAgent)){
            ChatEventVO chatEventVo = ChatEventVO.builder()
                    .eventData(result)
                    .eventType(ChatEventTypeEnum.DATA.getValue())
                    .build();
            return Flux.just(chatEventVo, STOP_EVENT);
        }

        // 4、如果智能体不为空，用对应的智能体，进一步处理用户的问题
        return nextAgent.streamChat(question,sessionId);
    }

    private static final Map<AgentTypeEnum,Agent> AGENT_MAP = new EnumMap<>(AgentTypeEnum.class);
    private Agent findAgentByType(AgentTypeEnum agentType){
        return AGENT_MAP.get(agentType);
    }

    @PostConstruct
    public void init(){
        Map<String, Agent> beansOfType = SpringUtil.getBeansOfType(Agent.class);
        for (Agent agent : beansOfType.values()) {
            AGENT_MAP.put(agent.getAgentType(),agent);
        }
    }

    /**
     * 2、打断会话 （Day1 - 随堂4）
     *
     * @param sessionId@return
     */
    @Override
    public void stop(String sessionId) {
        findAgentByType(AgentTypeEnum.ROUTE).stop(sessionId);
    }
}
